<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/21 0021
 * Time: 22:09
 */

namespace Lib\Core\WebSocket;


use Lib\Core\ConfigLoad;
use Lib\Core\HttpServer;
use Lib\Event\Event;
use Swoole\WebSocket\Server;

/**
 * @description:ws服务
 * @auth:yfl
 * @email:554665488@qq.com
 * Class WebSocketServer
 * @package Lib\Core\WebSocket
 */
class WebSocketServer extends HttpServer
{
    public function run()
    {
        //热重启
        //支持http请求 解析路由
        //能拥有webSocket控制器
        $config = ConfigLoad::getInstance();
        $config->load();//载入配置文件

        $wsSet = $config->get('ws');
        $this->server = new Server($wsSet['host'], $wsSet['port']);
        $this->server->set($wsSet['ws_setting']);
        $this->server->on('Start', [$this, 'start']);
        $this->server->on('workerStart', [$this, 'workerStart']);
        $this->server->on('handshake', [$this, 'handshake']);
        $this->server->on('open', [$this, 'open']);
        $this->server->on('message', [$this, 'message']);
        $this->server->on('close', [$this, 'close']);

        $this->registerEvent();//注册事件

        if ($wsSet['enable_http']) {
            $this->server->on('request', [$this, 'request']);
        }
        $this->server->start();
    }


    public function handshake(\swoole\Http\Request $request, \swoole_http_response $response)
    {
        $fd = $request->fd;
        $path = $request->server['path_info'];
        //保存了上下文信息
        WebSocketContext::init($fd, $path, $request);
        Event::trigger('ws.hand', ['server' => $this->server, 'request' => $request, 'response' => $response, 'redis' => $this->redis]);
    }

    /**
     * @description:分发open事件
     * @auth:yfl
     * @email:554665488@qq.com
     * @param $server
     * @param $request
     */
    public function open($server, $request)
    {
        echo '握手成功后执行open';
        $fd = $request->fd;
        $path = $request->server['path_info'];
        //保存了上下文信息
//        WebSocketContext::init($fd, $path);
        //全局事件优先
        Event::trigger('ws.open', ['server' => $server, 'request' => $request]);
        //触发到控制器,路由
        Dispatcher::open($server, $request, $path);
    }

    /**
     * @description:分发message事件
     * @auth:yfl
     * @email:554665488@qq.com
     * @param $server
     * @param $frame
     */
    public function message($server, $frame)
    {
        $fd = $frame->fd;
        $server->push($frame->fd, "this is server");
//        echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
//        if ($res = preg_match('/^(?P<url>((\d?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d?\d|1\d\d|2[0-4]\d|25[0-5]){1,3}):(?P<port>[\d]{4})_(?P<uid>[\d]+)/', $frame->data, $matches)) {
//            $uid = $matches['uid'];
//            $loginInfo = json_encode(['key' => $matches['url'] . ':' . $matches['port'], 'field' => 'uid_' . $uid]);
//            $this->redis->set('fd_' . $fd, $loginInfo);
//        }
//        获取了上下文信息
//        $server->tick(3000,function (){
//
//        });
        Event::trigger('ws.message', ['server' => $this->server, 'fd' => $fd, 'redis' => $this->redis, 'frame' => $frame]);
        $path = WebSocketContext::get($fd);
        Dispatcher::message($server, $frame, $path);
    }

    /**
     * @description:分发close事件
     * @auth:yfl
     * @email:554665488@qq.com
     * @param $server
     * @param $fd
     */
    public function close($server, $fd)
    {
        echo '客户端断开连接';
        $path = WebSocketContext::get($fd);
        //下线处理
        Event::trigger('ws.close', ['server' => $this->server, 'fd' => $fd, 'redis' => $this->redis]);
        Dispatcher::close($server, $fd, $path);
        //删除了上下文信息
        WebSocketContext::del($fd);
    }

    public function request($request, $response)
    {
        $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
    }
}